/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*************************************************************************
 * File: io.hpp
 *************************************************************************
 *\author: starlove
 *************************************************************************/

#ifndef __CC_PYTHON_IO_H__
#define __CC_PYTHON_IO_H__

#include <cocos2d.h>
#include "singleton.hpp"
#include <python_import_macro.h>
#include <sys/stat.h>
#include <stdio.h>

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#define ACCESS_MACRO _access
#else
#include <unistd.h>
#define ACCESS_MACRO access
#endif

NS_CCPY_BEGIN

	class CIOUtils
	{
		DECLARE_SINGLETON(CIOUtils)
	public:
		void Initialize(){};
		void Destroy(){};

		bool FileExists(const char *strPath)
		{
			return !ACCESS_MACRO(strPath, F_OK);
		}

		bool FileExists(std::string &strPath)
		{
			return FileExists(strPath.c_str());
		}

		bool FileCanRead(const char *strPath)
		{
			return !ACCESS_MACRO(strPath, F_OK | R_OK);
		}

		bool FileCanRead(std::string &strPath)
		{
			return FileCanRead(strPath.c_str());
		}

		bool FileCanWrite(const char *strPath)
		{
			return !ACCESS_MACRO(strPath, F_OK | W_OK);
		}

		bool FileCanWrite(std::string &strPath)
		{
			return FileCanWrite(strPath.c_str());
		}

		bool FileCanReadWrite(const char *strPath)
		{
			return !ACCESS_MACRO(strPath, F_OK | R_OK | W_OK);
		}

		bool FileCanReadWrite(std::string &strPath)
		{
			return FileCanReadWrite(strPath.c_str());
		}

		bool DirectoryExists(const char *strPath)
		{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
			struct stat __stat;
			return ((stat(strPath, &__stat) == 0) && (__stat.st_mode & _S_IFDIR));
#else
			struct stat __stat;
			return ((stat(strPath, &__stat) == 0) && S_ISDIR(__stat.st_mode));
#endif
		}

		bool DirectoryExists(std::string &strPath)
		{
			return DirectoryExists(strPath.c_str());
		}

		bool MakeDirectory(const char *strPath)
		{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
			return CreateDirectoryA(strPath, NULL) ? true : false;
#else
			return !mkdir(strPath, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
#endif
		}

		bool MakeDirectory(std::string &strPath)
		{
			return MakeDirectory(strPath.c_str());
		}

		unsigned long GetFileLength(const char *fp)
		{
			struct stat __stat;
			if (stat(fp, &__stat) == -1)
				return 0;
			return static_cast<unsigned long>(__stat.st_size);
		}

		bool CopyAssertFileToCwd(const char *srcF, const char *newF)
		{
			unsigned long fs = 0;
			unsigned char *data = cocos2d::CCFileUtils::sharedFileUtils()->getFileData(srcF, "rb", &fs);
			if(!data || !fs)
			{
				return false;
			}
			FILE *pf = fopen(newF, "wb");
			CCEXT_RETURN_IF(!pf, false);
			fwrite(data, fs, 1, pf);
			fclose(pf);
			return true;
		}

		bool CopyZipFileToCwd(const char *zipF, const char *srcF, const char *newF)
		{
			unsigned long fs = 0;
			unsigned char *data = cocos2d::CCFileUtils::sharedFileUtils()->getFileDataFromZip(zipF, srcF, &fs);
			if(!data || !fs)
			{
				return false;
			}
			FILE *pf = fopen(newF, "wb");
			CCEXT_RETURN_IF(!pf, false);
			fwrite(data, fs, 1, pf);
			fclose(pf);
			return true;
		}
		
		bool UnlinkFile(std::string &f)
		{
			return UnlinkFile(f.c_str());
		}

		bool UnlinkFile(const char *f)
		{
			return 0 == unlink(f);
		}
	};
NS_CCPY_END

#endif //!__CC_PYTHON_IO_H__